/**
 * @file		loader.h
 * @brief		loader
 * @note		None
 * @attention	None
 * 
 * <B><I>ALL RIGHTS RESERVED, COPYRIGHT&copy; SOCIONEXT INCORPORATED 2016</I></B>
 */

/** @weakgroup loader_overview
@{
	load function.<br>
@}*//* --- end of loader_overview */

#ifndef _LOADER_H_
#define _LOADER_H_

/** @weakgroup loader_definition
@{*/

/*********************/
/* factor definition */
/*********************/
/* 
  bit[7:4] module name
    0:Cortex-M0
    1:common
    2:Nand Flash Controller
    3:eMMC
    4:SD
    5:USB2.0
  bit[3:0] factor
    various factors
*/
#define FACT_M0_HARDFAULT	0x00	/**< Error factor : (M0)hard fault						*/
#define FACT_M0_NMI			0x01	/**< Error factor : (M0)NMI interrupt					*/
#define FACT_M0_OVERSIZE	0x10	/**< Error factor : (C) transfer size overflow			*/
#define FACT_M0_OUTOFRANGE	0x11	/**< Error factor : (C) transfer out of range			*/
#define FACT_M0_DEV_INI		0x12	/**< Error factor : (C) device initialization failure	*/
#define FACT_M0_HAD_READ	0x13	/**< Error factor : (C) headre read failure				*/
#define FACT_M0_IMAGE_READ	0x14	/**< Error factor : (C) Imege read failure				*/
#define FACT_M0_DIGEST_READ	0x15	/**< Error factor : (C) Digest read failure				*/
#define FACT_M0_SERIAL_READ	0x16	/**< Error factor : (C) Serial read failure				*/
#define FACT_M0_KEY_READ	0x17	/**< Error factor : (C) Key read failure				*/
#define FACT_M0_CHECKSUM	0x18	/**< Error factor : (C) sumcheck error					*/
#define FACT_NB_INIT		0x20	/**< Error factor : (NB)initialization failure			*/
#define FACT_NB_READ		0x21	/**< Error factor : (NB)read failure					*/
#define FACT_NB_ERASE		0x22	/**< Error factor : (NB)erase failure					*/
#define FACT_EM_INIT		0x20	/**< Error factor : (EM)initialization failure			*/
#define FACT_EM_READ		0x21	/**< Error factor : (EM)read failure					*/
#define FACT_EM_HW_ERROR	0x22	/**< Error factor : (EM)HW error						*/
#define FACT_EM_SWFAIL		0x2F	/**< Error factor : (EM)others software					*/
#define FACT_SD_NOCARD		0x40	/**< Error factor : (SD)card no inserted				*/
#define FACT_SD_OVERSIZE	0x41	/**< Error factor : (SD)transfer size overflow			*/
#define FACT_SD_READ		0x42	/**< Error factor : (SD)read failure					*/
#define FACT_TRACE			0xFF	/**< Error factor : (G) trace information				*/

/* definition */
#define RETRY_MAX	4	/**< maximum retry count							*/
#define BOOT_OK		0	/**< device control seccess							*/
#define BOOT_RETRY	1	/**< device control failue(retry is possible)		*/
#define BOOT_NG		-1	/**< device control failue(retry is not possible)	*/

/* Boot Mode definition */
#define BOOT_TYPE_NAND		0		/**< NAND Boot							*/
#define BOOT_TYPE_EMMC		1		/**< eMMC Boot							*/
#define BOOT_TYPE_USB		2		/**< USB2.0 Writer						*/
#define BOOT_TYPE_SDCH2		3		/**< SD ch2 Writer						*/
#define BOOT_TYPE_SDCH3		4		/**< SD ch3 Writer						*/
#define BOOT_TYPE_DEBUG		5		/**< debug mode							*/
#define BOOT_TYPE_NFECC		6		/**< NAND Boot with ECC control			*/
#define BOOT_TYPE_NFDEF		7		/**< NAND Boot default timing			*/
#define BOOT_TYPE_NFSEC		8		/**< Secure NAND Boot					*/
#define BOOT_TYPE_EMSEC		9		/**< Secure eMMC Boot					*/
#define BOOT_TYPE_NFECCSEC	14		/**< Secure NAND Boot with ECC control	*/
#define BOOT_TYPE_NFDEFSEC	15		/**< Secure NAND Boot default timing	*/
#define BOOT_TYPE_DEF		0xFF	/**< initial value						*/
#define BOOT_TYPE_SEC_MSK	0x07	/**< Secure mask 						*/


/**
 * @enum  E_EFFO_OFFSET
 * @brief EFFO offset definition
 *
 */
typedef enum {
	E_EFFO_00 = 0,
	E_EFFO_01,
	E_EFFO_02,
	E_EFFO_03,
	E_EFFO_04,
	E_EFFO_05,
	E_EFFO_06,
	E_EFFO_07,
	E_EFFO_08,
	E_EFFO_09,
	E_EFFO_10,
	E_EFFO_11,
	E_EFFO_12,
	E_EFFO_13,
	E_EFFO_14,
	E_EFFO_15,
	E_EFFO_16,
	E_EFFO_17,
	E_EFFO_18,
	E_EFFO_19,
	E_EFFO_20,
	E_EFFO_21,
	E_EFFO_22,
	E_EFFO_23,
	E_EFFO_24,
	E_EFFO_25,
	E_EFFO_26,
	E_EFFO_27,
	E_EFFO_28,
	E_EFFO_29,
	E_EFFO_30,
	E_EFFO_31,
	E_EFFO_32,
	E_EFFO_33,
	E_EFFO_34,
	E_EFFO_35,
	E_EFFO_36,
	E_EFFO_37,
	E_EFFO_38,
	E_EFFO_39,
	E_EFFO_40,
	E_EFFO_41,
	E_EFFO_42,
	E_EFFO_43,
	E_EFFO_44,
	E_EFFO_45,
	E_EFFO_46,
	E_EFFO_47,
	E_EFFO_48,
	E_EFFO_49,
	E_EFFO_50,
	E_EFFO_51,
	E_EFFO_52,
	E_EFFO_53,
	E_EFFO_54,
	E_EFFO_55,
	E_EFFO_56,
	E_EFFO_57,
	E_EFFO_58,
	E_EFFO_59,
	E_EFFO_60,
	E_EFFO_61,
	E_EFFO_62,
	E_EFFO_63
} E_EFFO_OFFSET;

/**
 * @struct T_BOOT_MODE_FIELDS
 * @brief  boot header
 *
 */
typedef struct {
	unsigned long bmfRetryModeEna;		/**< enable control of retry mode */
	unsigned long bmfToggleTImeError;	/**< toggle for time error */
} T_BOOT_MODE_FIELDS;

/** boot header */
typedef struct {
	unsigned long bhVersion;			/**< version number				*/
	unsigned long bhCopyAddr;			/**< copy address(SRAM)			*/
	unsigned long bhExcuteAddr;			/**< excute address				*/
	unsigned long bhImageSize;			/**< image size					*/
	unsigned long bhImageOffset;		/**< image offset				*/
	unsigned long bhDigestOffset;		/**< digest offset				*/
	unsigned long bhSNOffset;			/**< serial number offset		*/
	unsigned long bhKeySize;			/**< key size					*/
	unsigned long bhReserved[6];		/**< reserved					*/
	T_BOOT_MODE_FIELDS bhBootMode;		/**< boot mode					*/
} boot_header;

/** sdram parameter */
typedef struct {
	unsigned long	DDR_SDRAM_TM_SPEC0;		/**< SDRAM Timing-spec 0.									*/
	unsigned long	DDR_SDRAM_TM_SPEC1;		/**< SDRAM Timing-spec 1.									*/
	unsigned long	DDR_SDRAM_TM_SPEC2;		/**< SDRAM Timing-spec 2.									*/
	unsigned long	DDR_SDRAM_TM_SPEC3;		/**< SDRAM Timing-spec 3.									*/
	unsigned long	DDR_SDRAM_TM_SPEC4;		/**< SDRAM Timing-spec 4.									*/
	unsigned long	DDR_SDRAM_MRW0;			/**< SDRAM MRW 0.											*/
	unsigned long	DDR_SDRAM_MRW1;			/**< SDRAM MRW 1.											*/
	unsigned long	DDR_PHY_INIT2;			/**< PHY initial setting-2.									*/
	unsigned long	DDR_IO_INIT1;			/**< I/O initial setting-1.									*/
	unsigned long	DDR_IO_INIT3;			/**< I/O initial setting-3.									*/
	unsigned long	DDR_PZQ_INIT;			/**< PZQ initial setting.									*/
	unsigned long	DDR_TR_MODE;			/**< training mode.											*/
	unsigned long	DDR_TXCA_CH_DLY;		/**< per-Channel delay value(TXCA).							*/
	unsigned long	DDR_TXDQS_BYTE_DLY0;	/**< per-Byte delay value (TXDQS and TXDQ) 0.				*/
	unsigned long	DDR_TXDQS_BYTE_DLY1;	/**< per-Byte delay value (TXDQS and TXDQ) 1.				*/
	unsigned long	DDR_TXDQS_BYTE_DLY2;	/**< per-Byte delay value (TXDQS and TXDQ) 2.				*/
	unsigned long	DDR_TXDQS_BYTE_DLY3;	/**< per-Byte delay value (TXDQS and TXDQ) 3.				*/
	unsigned long	DDR_RXRTT_BYTE_DLY0;	/**< per-Byte delay value(RXDQS and RXRTT) 0.				*/
	unsigned long	DDR_RXRTT_BYTE_DLY1;	/**< per-Byte delay value(RXDQS and RXRTT) 1.				*/
	unsigned long	DDR_RXRTT_BYTE_DLY2;	/**< per-Byte delay value(RXDQS and RXRTT) 2.				*/
	unsigned long	DDR_RXRTT_BYTE_DLY3;	/**< per-Byte delay value(RXDQS and RXRTT) 3.				*/
	unsigned long	DDR_RDDATA_LAT0;		/**< Read data synchronizer (RDDATA_LAT) 0.					*/
	unsigned long	DDR_RDDATA_LAT1;		/**< Read data synchronizer (RDDATA_LAT) 1.					*/
	unsigned long	DDR_RDDATA_LAT2;		/**< Read data synchronizer (RDDATA_LAT) 2.					*/
	unsigned long	DDR_RDDATA_LAT3;		/**< Read data synchronizer (RDDATA_LAT) 3.					*/
	unsigned long	DDR_TR_SEQ;				/**< Training sequencer setting-1.							*/
	unsigned long	DDR_TR_PTN_CA;			/**< Training pattern selection (CA).						*/
	unsigned long	DDR_TR_PTN_WRDE;		/**< Training pattern selection(RDE, WDE).					*/
	unsigned long	DDR_TXCA_CH_RANGE;		/**< per-Chennel sweep range (TXCA CA training).			*/
	unsigned long	DDR_TXDQS_RANGE0;		/**< sweep range (TXDQS write leveling) 0.					*/
	unsigned long	DDR_TXDQS_RANGE1;		/**< sweep range (TXDQS write leveling) 1.					*/
	unsigned long	DDR_TXDQS_RANGE2;		/**< sweep range (TXDQS write leveling) 2.					*/
	unsigned long	DDR_TXDQS_RANGE3;		/**< sweep range (TXDQS write leveling) 3.					*/
	unsigned long	DDR_RXDQS_BYTE_RANGE0;	/**< pre-Byte sweep range (RXDQS read data eye training) 0.	*/
	unsigned long	DDR_RXDQS_BYTE_RANGE1;	/**< pre-Byte sweep range (RXDQS read data eye training) 1.	*/
	unsigned long	DDR_RXDQS_BYTE_RANGE2;	/**< pre-Byte sweep range (RXDQS read data eye training) 2.	*/
	unsigned long	DDR_RXDQS_BYTE_RANGE3;	/**< pre-Byte sweep range (RXDQS read data eye training) 3.	*/
	unsigned long	DDR_TXDQ_BYTE_RANGE0;	/**< pre-Byte sweep range (TXDQ write data eye training) 0.	*/
	unsigned long	DDR_TXDQ_BYTE_RANGE1;	/**< pre-Byte sweep range (TXDQ write data eye training) 1.	*/
	unsigned long	DDR_TXDQ_BYTE_RANGE2;	/**< pre-Byte sweep range (TXDQ write data eye training) 2.	*/
	unsigned long	DDR_TXDQ_BYTE_RANGE3;	/**< pre-Byte sweep range (TXDQ write data eye training) 3.	*/
	unsigned long	UMCINITCTLA;			/**< DRAM initialization command interval setting A.		*/
	unsigned long	UMCINITCTLB;			/**< DRAM initialization command interval setting B.		*/
	unsigned long	UMCINITCTLC;			/**< DRAM initialization command interval setting C.		*/
	unsigned long	UMCDRMMRA;				/**< DRAM initialization MR setting.						*/
	unsigned long	UMCMEMCONF0A;			/**< DRAM parameter	setting A-Rank0.						*/
	unsigned long	UMCMEMCONF0B;			/**< DRAM parameter	setting B-Rank0.						*/
	unsigned long	UMCMEMCONF1A;			/**< DRAM parameter	setting A-Rank1.						*/
	unsigned long	UMCMEMCONF1B;			/**< DRAM parameter	setting B-Rank1.						*/
	unsigned long	UMCMEMCONFCH;			/**< DRAM parameter	setting Channel.						*/
	unsigned long	UMCMEMMAPSET;			/**< DRAM mapping setting.									*/
	unsigned long	UMCCMDCTLA;				/**< DRAM command interval setting A.						*/
	unsigned long	UMCCMDCTLB;				/**< DRAM command interval setting B.						*/
	unsigned long	UMCCMDCTLC;				/**< DRAM command interval setting C.						*/
	unsigned long	UMCCMDCTLD;				/**< DRAM command interval setting D.						*/
	unsigned long	UMCCMDCTLE;				/**< DRAM command interval setting E.						*/
	unsigned long	UMCCMDCTLF;				/**< DRAM command interval setting F.						*/
	unsigned long	UMCCMDCTLG;				/**< DRAM command interval setting G.						*/
	unsigned long	UMCCMDCTLH;				/**< DRAM command interval setting H.						*/
	unsigned long	UMCCMDCTLI;				/**< DRAM command interval setting I.						*/
	unsigned long	UMCCMDCTLJ;				/**< DRAM command interval setting J.						*/
	unsigned long	UMCRDATACTL_D0;			/**< DRAM read data interval control 0.						*/
	unsigned long	UMCRDATACTL_D1;			/**< DRAM read data interval control 1.						*/
	unsigned long	UMCWDATACTL_D0;			/**< DRAM write data interval control 0.					*/
	unsigned long	UMCWDATACTL_D1;			/**< DRAM write data interval control 1.					*/
	unsigned long	UMCDATASET;				/**< DRAM command issue timing control.						*/
	unsigned long	UMCWDATASWP;			/**< DRAM write data swap.									*/
	unsigned long	REMAPADDR;				/**< Remap address setting.									*/
} sdram_parameter;

/** nand parameter */
typedef struct {
	unsigned long	nf_clk_sel;					/**< Clock selector.											*/
	unsigned long	common_settings;			/**< Common setting.											*/
	unsigned long	toggle_timings_0;			/**< Toggle timing 0.											*/
	unsigned long	toggle_timings_1;			/**< Toggle timing 1.											*/
	unsigned long	async_toggle_timings;		/**< Asynchronous toggle timing.								*/
	unsigned long	sync_timings;				/**< Synchronizing timing.										*/
	unsigned long	timings0;					/**< Timing 0.													*/
	unsigned long	timings1;					/**< Timing 1.													*/
	unsigned long	timings2;					/**< Timing 2.													*/
	unsigned long	dll_phy_ctrl;				/**< DLL-PHY control.											*/
	unsigned long	phy_ctrl_reg;				/**< PHY control.												*/
	unsigned long	phy_tsel_reg;				/**< PHY Tsel.													*/
	unsigned long	phy_dq_timing_reg;			/**< PHY Dq Timing.												*/
	unsigned long	phy_dqs_timing_reg;			/**< PHY Dqs Timing.											*/
	unsigned long	phy_gate_lpbk_ctrl_reg;		/**< PHY gate lpbk control.										*/
	unsigned long	phy_dll_master_ctrl_reg;	/**< PHY DLL master control.									*/
	unsigned long	phy_dll_slave_ctrl_reg;		/**< PHY DLL slave control.										*/
	unsigned long	timing_mode;				/**< timing mode.												*/
	unsigned long	dbcnt;						/**< driving force control.										*/
	unsigned long	ecc_config;					/**< Ecc config.												*/
	unsigned long	skip_bytes_conf;			/**< Skip bytes config.											*/
	unsigned long	skip_bytes_offset;			/**< Skip bytes offset.											*/
	unsigned long	rsvd;						/**< Reserved.													*/
	unsigned long	cache_read_enable;			/**< Cache read enable.											*/
	unsigned long	FACTOR_CHECK;				/**< factory defect check.										*/
	unsigned long	factor_check_search_page;	/**< Page number to be used in the search of the bad block.<br>
													 (page0 is check at fixed.)									*/
} nand_parameter;

/** boot parameter */
typedef struct {
	boot_header		header;				/**< boot header				*/
	unsigned long	ptable_sel[3];		/**< partition table selector	*/
	unsigned long	PLLCNTL1_B;			/**< PLLCNTL1 Register (Before)	*/
	unsigned long	PLLCNTL1_A;			/**< PLLCNTL1 Register (After)	*/
	unsigned long	PLLCNTL7;			/**< PLLCNTL7 Register			*/
	sdram_parameter	sdram_parh[2];		/**< sdram parameter			*/
	nand_parameter 	nand_par;			/**< nand parameter				*/
} boot_parameter;

/** Partition Table Detail Information */
typedef struct {
	unsigned long	load_addr;			/**< Data the destination address.	*/
	unsigned long	jump_addr;			/**< Jump Address.					*/
	unsigned long	sector_num;			/**< Start sector number.			*/
	unsigned long	data_size;			/**< Data size [byte].				*/
	unsigned long	num_of_blocks;		/**< Use the number of blocks.		*/
#ifdef CO_MEMORY_1GB
	unsigned short	lut[880];			/**< Look up table.					*/
#else	// CO_MEMORY_1GB
	unsigned short	lut[512];			/**< Look up table.					*/
#endif	// CO_MEMORY_1GB
	unsigned long	message_digest[8];	/**< Message digest.				*/
} partition_detail;

/** Partition Table */
typedef struct {
	unsigned long		area_size;		/**< partition area(area0/area1) total size.	*/
	unsigned long		selector;		/**< Use area(area0/area1).						*/
	partition_detail	area[2];		/**< detail information.						*/
} partition_table;

/** Partition Table Block */
typedef struct {
	unsigned short		block_data;		/**< Block Data.	*/
	unsigned short		reserved;		/**< Reserved.		*/
} partition_table_block;

/** variable for MDR port */
extern volatile unsigned long g_MDR_value;

/* @} */	// loader_definition group

/** @weakgroup loader_func
@{*/


/**
load procedure
@retval  0 : success
@retval -1 : failure
*/
int load_procedure();

/**
SDRAMC Start from Self Refresh
*/
void sdram_self_refresh_start();

/**
Save the DDR-PHY Register values before transition to self-refresh.
*/
void ddr_reg_save_self_refresh();

/**
Wait
@param [in] wait_time	Wait time.<br>
						PLL Clock = 100MHz : 1 = 130nsec.<br>
						PLL Clock =  32KHz : 1 = 440usec.<br>
*/
void wait( int wait_time );

/**
Assertion<br>
Processing interrupted, and turn on the ALARM LED(red).
*/
void assertion();

/* @} */	// loader_func group

#endif	// _LOADER_H_
